package com.zenika.zenbinding.client.feedback;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.zenika.zenbinding.client.exception.DataMessage;
import com.zenika.zenbinding.client.handler.Handler;

/**
 * The EnumFeedbackManager shows error message list of Models in error state.
 * The place where the list is locate is pointed by an id given in the
 * contructor. This FeedbackManager manages the feedback for multiple Model.<br>
 * By default, the displayed message is the cause of the error. If you want the
 * message to contain the name of the model causing the error, you have to
 * specify a name to the model.
 * @author Zenika
 */
public class EnumFeedbackManager implements FeedbackManager {

	private Map<Handler,DataMessage> messageMap;
	private Element element;
	private Element list;

	{
		this.messageMap = new HashMap<Handler,DataMessage>();
	}

	/**
	 * Give an EnumFeedbackManager which message will be located in the element
	 * having this id.
	 * @param id
	 */
	public EnumFeedbackManager(String id) {
		this.element = DOM.getElementById(id);
		this.list = DOM.createElement("ul");
		DOM.appendChild(this.element, this.list);
	}

	public void enterErrorState(DataMessage message, Handler handler) {
		this.messageMap.put(handler, message);
		this.refresh();
	}

	public void leaveErrorState(Handler handler) {
		this.messageMap.remove(handler);
		this.refresh();
	}

	private void refresh() {
		DOM.removeChild(this.element, this.list);
		this.list = DOM.createElement("ul");
		Collection<DataMessage> messages = this.messageMap.values();
		Iterator<DataMessage> iter = messages.iterator();
		while (iter.hasNext()) {
			DataMessage message = iter.next();
			Element messageElement = DOM.createElement("li");
			DOM.setInnerText(messageElement, message.getMessage());
			DOM.appendChild(this.list, messageElement);
		}
		DOM.appendChild(this.element, this.list);
	}
}
